package com.t2t.top.ldap;

import javax.naming.AuthenticationException;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.BasicAttributes;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.Control;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;
import java.util.Hashtable;

public class LdapAuth {
    private final String URL = "ldap://101.200.161.144:389/";
    private final String BASEDN = "dc=t2t,dc=com";   // 域
    private final String DOMAIN = "ou=people";         // 组
    private final String FACTORY = "com.sun.jndi.ldap.LdapCtxFactory";
    private LdapContext ctx = null;
    private final Control[] connCtls = null;

    private void connect() {
        Hashtable<String, String> env = new Hashtable<String, String>();
        env.put(Context.INITIAL_CONTEXT_FACTORY, FACTORY);
        env.put(Context.PROVIDER_URL, URL + BASEDN);
        env.put(Context.SECURITY_AUTHENTICATION, "simple");

        String root = "cn=admin,dc=t2t,dc=com";  //根据自己情况修改
        env.put(Context.SECURITY_PRINCIPAL, root);   // 管理员
        env.put(Context.SECURITY_CREDENTIALS, "admin");  // 管理员密码

        try {
            ctx = new InitialLdapContext(env, connCtls);
            System.out.println("连接成功");
        } catch (AuthenticationException e) {
            System.out.println("连接失败：");
            e.printStackTrace();
        } catch (Exception e) {
            System.out.println("连接出错：");
            e.printStackTrace();
        }

    }

    private void closeContext() {
        if (ctx != null) {
            try {
                ctx.close();
            } catch (NamingException e) {
                e.printStackTrace();
            }

        }
    }

    private String getUserDN(String uid) {
        String fullName = "";
        try {
            SearchControls constraints = new SearchControls();
            constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);

            NamingEnumeration<SearchResult> en = ctx.search("", "uid=" + uid, constraints);

            if (en == null || !en.hasMoreElements()) {
                System.out.println("未找到该用户");
            }

            while (en != null && en.hasMoreElements()) {
                Object obj = en.nextElement();
                if (obj instanceof SearchResult) {
                    SearchResult si = (SearchResult) obj;
                    fullName += si.getName();
                    fullName += "," + BASEDN;
                } else {
                    System.out.println(obj);
                }
            }
        } catch (Exception e) {
            System.out.println("查找用户时产生异常。");
            e.printStackTrace();
        }

        return fullName;
    }

    public boolean authenricate(String UID, String password) {
        //String fullName2 = getUserDN(UID);
        String fullName = getUDN(UID);
        System.out.println("fullName:" + fullName + ",password:" + password);
        //System.out.println("fullName:" + fullName2 + ",password:" + password);
        try {
            connect();
            ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, fullName);
            ctx.addToEnvironment(Context.SECURITY_CREDENTIALS, password);
            ctx.reconnect(connCtls);
            System.out.println(fullName + " 验证通过");
            return true;
        } catch (AuthenticationException e) {
            System.out.println(fullName + " 验证失败");
            System.out.println(e.toString());
            return false;
        } catch (Exception e) {
            System.out.println(fullName + " 验证失败");
            System.out.println(e.toString());
            return false;
        } finally {
            closeContext();
        }
    }

    private boolean addUser(String uid, String pwd, String sn, String cn, String email) {
        try {
            connect();
            String subName = getUDN(uid);
            BasicAttributes attrsbu = new BasicAttributes();
            attrsbu.put("uid", uid);
            attrsbu.put("objectClass", "inetOrgPerson");
            attrsbu.put("userPassword", pwd);
            attrsbu.put("labeledURI", email);
            attrsbu.put("sn", sn);
            attrsbu.put("cn", cn);
            ctx.createSubcontext("uid=" + uid + "," + DOMAIN, attrsbu);
            return true;
        } catch (NamingException ex) {
            ex.printStackTrace();
        }
        closeContext();
        return false;
    }

    private String getUDN(String usr) {
        return getSubDN(usr) + "," + BASEDN;
    }

    private String getSubDN(String usr) {
        return "uid=" + usr + "," + DOMAIN;
    }

    public static void main(String[] args) {
        LdapAuth ldap = new LdapAuth();
        String user = "zhangsanfeng";
        String pwd = "123456";
        if (ldap.authenricate(user, pwd)) {
            System.out.println("该用户认证成功");
            return;
        }

        System.out.println("创建用户" + user);
        System.out.println(ldap.addUser(user, pwd, "张", "三丰", "zhangsanfeng@qq.com"));
    }
}